package com.gosophia.logContent.LogAspectService;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.xwork.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.context.SecurityContextHolder;

import com.gosophia.commons.web.action.BaseSupportAction;
import com.gosophia.commons.web.logAnnotation.LogRecord;
import com.gosophia.logManagement.dto.LogContentDTO;
import com.gosophia.logManagement.ws.LogManagementWebService;
import com.gosophia.springsecurity.UserDetailsImpl;

 public class LogAspect {

	@Autowired
	private LogManagementWebService logManagementService;
	
	private Log logger = LogFactory.getLog(LogAspect.class); 
	
	@SuppressWarnings("unchecked")
	public void doSystemLog(JoinPoint point) throws Throwable {
		String methodName = point.getSignature().getName();
		//目标方法不为空
		if(StringUtils.isNotEmpty(methodName)) {
		   //set与get方法除外
		   if(methodName.startsWith("_exe")) {
			 
			   Class targetClass = point.getTarget().getClass();
			   Method method =  targetClass.getMethod(methodName);
			   
			   if(method!=null){
				   boolean hasAnnotation = method.isAnnotationPresent(LogRecord.class);
				   if(hasAnnotation) {
					   LogRecord annotation = method.getAnnotation(LogRecord.class);
					   String methodDescp = annotation.eventAction();
					   String targetc =  annotation.eventTarget();
					   String DtoTarget;
					   Field h = null;
					   Class<? extends Object> myClass = point.getTarget().getClass();
					   
					   //连同父类中的方法一起查找
					   while (!myClass.equals(BaseSupportAction.class) 
							   && !myClass.equals(Object.class)){
						   try{
							   h = myClass.getDeclaredField(targetc);
						   }catch (NoSuchFieldException e) {
							// TODO: handle exception
						   }catch (SecurityException e) {
							// TODO: handle exception
						   }
						   
						   if (h != null){
							   break;
						   }
						   
						   myClass = point.getTarget().getClass().getSuperclass();
					   }
					   					   
					   Boolean bAccessible = h.isAccessible();
					   h.setAccessible(true);
                       
			           if(h.get(point.getTarget()).toString().length()>2000){
			        	   DtoTarget = h.get(point.getTarget()).toString().substring(0, 2000);   
			           } else {
			        	   DtoTarget = h.get(point.getTarget()).toString();
			           }
					   
					   h.setAccessible(bAccessible);

					   //取到当前的操作用户
				  		UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder
						.getContext().getAuthentication().getPrincipal();
				  	  
					   if(userDetails!=null) {
						   try {
							   LogContentDTO logContent = new LogContentDTO();
							    // 用户IP地址
								HttpServletRequest request = ServletActionContext.getRequest();

								// 当用户使用了代理服务器时
								String ip = request.getHeader("x-forwarded-for");
								if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
									ip = request.getHeader("Proxy-Client-IP");
								}
								if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
									ip = request.getHeader("WL-Proxy-Client-IP");
								}
								if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
									ip = request.getRemoteAddr();
								}
								//用户IP
								logContent.setEventResource(ip);
								// 当前时间
								Date now = new Date(System.currentTimeMillis());
								DateFormat date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置显示格式
								String dateString = date.format(now);
								// 操作时间
								logContent.setEventTime(dateString);
								// 操作当前账户
								logContent.setEventUserAccountName(userDetails.getUsername());
								// 用户操作行为
								logContent.setEventAction(methodDescp);
								// 用户信息
								logContent.setLogMessage(DtoTarget);
								// 添加日志
								logManagementService.addLogContent(logContent);
						   } catch(Exception ex) {
							   logger.error(ex.getMessage());
						   }
					   }
					   
				   }
			   }
		   }
		}
		
	}
}
